package com.sxj.corejava.code07_stream;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 石小俊
 * @date 2023年12月2023/12/23日 14:14
 */
public class Test03_终止操作 {

    private static List<Integer> list = Arrays.asList(1, 4, 5, 7, 8, 3, 6, 13, 19, 15, 12, 2, 4);

    public static void main(String[] args) {
//        allMatchTest();
//        anyMatchTest();
//        noneMatchTest();
//        findFirstTest();
//        findAnyTest();
//        countTest();
//        maxTest();
//        minTest();
//        reduceTest();
        collectTest();
    }

    public static void allMatchTest() {
        boolean flag = list.stream()
                // 检查流中元素是否都大于1
                // 只要有任意一个不符合,则返回false
                .allMatch(i -> i > 1);
        System.out.println(flag);
    }

    public static void anyMatchTest() {
        boolean flag = list.stream()
                // 检查流中元素是否存在偶数
                // 只要有任意一个符合,则返回true
                .anyMatch(i -> i % 2 == 0);
        System.out.println(flag);
    }

    public static void noneMatchTest() {
        // 检查流中所有元素是否都不满足指定规则
        boolean flag = list.stream()
                // 检查流中元素是否都不小于0
                // 只要有任意一个符合,则返回false
                .noneMatch(i -> i < 0);
        System.out.println(flag);
    }

    public static void findFirstTest() {
//        list = new ArrayList<>();
        // 取出指定流中的第一个元素
        // 此时方法的返回值不是具体的元素的值,而是一个存放元素的容器
        Optional<Integer> first = list.stream().findFirst();
        // 可以通过get方法从容器中取出值
        // 但是可能存在容器中没有纸的情况,如果没有值,取值时会报错
//        System.out.println(first.get());
        // 因此,取值前可以先进行判断,判断其是否有值
//        int num;
//        if(first.isPresent()){
//            // 如果有值,取出对应的值
//            num = first.get();
//        } else{
//            // 如果没有纸,可以设置一个默认值
//            // 为变量设置了一个默认值
//            num = 0;
//        }
//        System.out.println(num);

        // 从容器中获取对应的值
        // 如果容器中存在值,则直接返回
        // 如果容器中不存在值,则向容器中存储一个默认值并返回
        System.out.println(first.orElse(0));
    }

    public static void findAnyTest() {
        new Thread() {
            @Override
            public void run() {
                System.out.println("线程1:" + list.parallelStream().findAny().get());
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                System.out.println("线程2:" + list.parallelStream().findAny().get());
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                System.out.println("线程3:" + list.parallelStream().findAny().get());
            }
        }.start();
    }

    public static void countTest() {
        long count = list.stream()
                .count();
        System.out.println("流中元素数量:" + count);
    }

    public static void maxTest() {
        // max方法表示从排序后的结果中取出最后一个元素
        // 因此,想要通过max()获取最大值,必须通过升序排序
        Optional<Integer> max = list.stream().max((a, b) -> a - b);
        System.out.println(max.get());
        Optional<Integer> max2 = list.stream().max((a, b) -> b - a);
        System.out.println(max2.get());
    }

    public static void minTest() {
        // min方法表示从排序后的结果中取出第一个元素
        // 因此,想要min()获取最小值,必须通过升序排序
        Optional<Integer> min = list.stream().min((a, b) -> a - b);
        System.out.println(min.get());
        Optional<Integer> min2 = list.stream().min((a, b) -> b - a);
        System.out.println(min2.get());
    }

    public static void reduceTest() {
        Optional<Integer> reduce = Stream.iterate(1, i -> i + 1)
                .limit(100)
//                .reduce((a, b) -> a + b);
                .reduce(Integer::sum);
        System.out.println(reduce.get());
    }

    public static void collectTest() {
        List<Integer> list2 = list.stream()
                .filter(i -> i % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(list2);
        Set<Integer> set = list.stream()
                .filter(i -> i % 2 == 0)
                .collect(Collectors.toSet());
        System.out.println(set);

    }
}
